Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

windows-gnullvm: Avoid linking to libunwind statically #121794

Conversation

kleisauke
Copy link
Contributor

@kleisauke kleisauke commented Feb 29, 2024

Avoid linking against the static variant of libunwind, which is not always available. Instead, prefer to use the unwind library from the toolchain, which the linker will automatically include, depending on what's available.

@kleisauke

This comment was marked as resolved.

@rustbot
Copy link
Collaborator

rustbot commented Feb 29, 2024

r? @fmease

rustbot has assigned @fmease.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot
Copy link
Collaborator

rustbot commented Feb 29, 2024

Failed to set assignee to mati865: invalid assignee

Note: Only org members with at least the repository "read" role, users with write permissions, or people who have commented on the PR may be assigned.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 29, 2024
@rustbot
Copy link
Collaborator

rustbot commented Feb 29, 2024

These commits modify compiler targets.
(See the Target Tier Policy.)

@rust-log-analyzer

This comment has been minimized.

@kleisauke kleisauke force-pushed the windows-gnullvm-change-unwind-linkage branch from 71a9b1b to ba888f8 Compare February 29, 2024 12:18
@rust-log-analyzer

This comment has been minimized.

@kleisauke kleisauke force-pushed the windows-gnullvm-change-unwind-linkage branch from ba888f8 to 5b24cc1 Compare February 29, 2024 12:24
@mati865
Copy link
Contributor

mati865 commented Feb 29, 2024

I don't see how crt-static would affect libunwind linkage with these changes. I think it would require special handling like here:

#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
#[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
extern "C" {}

I'll test it during the weekend.

Also I think it might be the best to just build the unwinder during Rust build and always link it statically like here:

#[link(name = "unwind", kind = "static", modifiers = "-bundle")]

Avoid linking against the static variant of libunwind, which is not
always available. Instead, prefer to use the unwind library from the
toolchain, which the linker will automatically include, depending
on what's available.
@kleisauke kleisauke force-pushed the windows-gnullvm-change-unwind-linkage branch from 5b24cc1 to 7af0f34 Compare March 1, 2024 08:29
@kleisauke
Copy link
Contributor Author

Ah, you're right, it looks like that only applies to Linux and Fuchsia targets.

# Only applies for Linux and Fuchsia targets
# If crt-static is enabled, static link to `libunwind.a` provided by system
# If crt-static is disabled, dynamic link to `libunwind.so` provided by system
system-llvm-libunwind = []

I just clarified my commit message.

FWIW, here's a Dockerfile to reproduce this:

Details
# Build with:
# docker build -t llvm-mingw .
FROM docker.io/mstorsjo/llvm-mingw:latest

# Supported architectures: x86_64, i686, aarch64 and armv7
ARG ARCH=x86_64

# Path settings
ENV RUSTUP_HOME="/usr/local/rustup" \
    CARGO_HOME="/usr/local/cargo" \
    PATH="/usr/local/cargo/bin:$PATH"

# Install curl
RUN apt-get update -qq && \
    apt-get install -qqy --no-install-recommends curl && \
    apt-get clean -y && \
    rm -rf /var/lib/apt/lists/*

# Install Rust
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y \
      --no-modify-path \
      --profile minimal \
      --target $ARCH-pc-windows-gnullvm \
      --default-toolchain nightly \
      --component rust-src

WORKDIR /build

# Special flags for Rust
ENV CARGO_PROFILE_RELEASE_DEBUG=false \
    CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1 \
    CARGO_PROFILE_RELEASE_INCREMENTAL=false \
    CARGO_PROFILE_RELEASE_LTO=true \
    CARGO_PROFILE_RELEASE_OPT_LEVEL=z \
    CARGO_PROFILE_RELEASE_PANIC=abort

RUN rm /opt/llvm-mingw/$ARCH-w64-mingw32/lib/libunwind.a

RUN cargo new foo --lib --vcs none && \
    cd foo && \
    echo "pub fn foo() {}" > src/lib.rs && \
    cargo rustc --release --crate-type=cdylib --target=$ARCH-pc-windows-gnullvm -Zbuild-std=std,panic_abort && \
    llvm-readobj --coff-imports target/$ARCH-pc-windows-gnullvm/release/foo.dll

@fmease
Copy link
Member

fmease commented Mar 1, 2024

Not my area of expertise
r? compiler

@rustbot rustbot assigned nnethercote and unassigned fmease Mar 1, 2024
@nnethercote
Copy link
Contributor

r? @petrochenkov
cc @mati865

@rustbot rustbot assigned petrochenkov and unassigned nnethercote Mar 1, 2024
@mati865
Copy link
Contributor

mati865 commented Mar 2, 2024

The problem linking dynamic libunwind is the need of shipping libunwind together with the library/binary. I'll try if I can get crt-static feature to work or build libunwind together with std.

@kleisauke
Copy link
Contributor Author

Ah, I see. LLVM just uses -lunwind, so it will link against the static libunwind.a variant when libunwind.dll{,.a} is not available.
https://github.com/llvm/llvm-project/blob/llvmorg-17.0.6/clang/lib/Driver/ToolChains/CommonArgs.cpp#L1829-L1831

If you pass -Clink-args=-static-libgcc, it will forcibly link against libunwind.a, but this is a bit odd from a Rust point of view. I'll close.

@mati865
Copy link
Contributor

mati865 commented Mar 4, 2024

Opened #122003 that builds libunwind for these targets so we become independent of host toolchain when it comes to libunwind. Did some testing during Sunday and it seems to work fine but I'll try it with your Dockerfile using toolchain built the official way.

bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 5, 2024
…try>

Build libunwind for pc-windows-gnullvm

Alternative to rust-lang#121794

The changes in this PR:
- build libunwind for `pc-windows-gnullvm` targets
- join paths with `join()` instead of slashes to avoid mixing slashes on windows, this changes it them from `"H:\\projects\\rust\\src/llvm-project/libunwind\\include"` to `"H:\\projects\\rust\\src\\llvm-project\\libunwind\\include"`
- include `libunwind/src`, some of the includes are located inside `src` and without this change the build fails with:
```
running: "h:/msys64/clang64/bin/clang++.exe" "-O3" "-ffunction-sections" "-fdata-sections" "--target=x86_64-pc-windows-gnullvm" "-I" "H:\\projects\\rust\\src\\llvm-project\\libunwind\\include" "-nostdinc++" "-fno-exceptions" "-fno-rtti" "-fstrict-aliasing" "-funwind-tables" "-fvisibility=hidden" "-fvisibility-global-new-delete-hidden" "-D_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS" "-D_LIBUNWIND_HIDE_SYMBOLS=1" "-D_LIBUNWIND_IS_NATIVE_ONLY=1" "-o" "H:\\projects\\rust\\build\\x86_64-pc-windows-gnullvm\\native\\libunwind\\Unwind-EHABI.o" "-c" "\\\\?\\H:\\projects\\rust\\src\\llvm-project\\libunwind\\src\\Unwind-EHABI.cpp"
cargo:warning=\\?\H:\projects\rust\src\llvm-project\libunwind\src\Unwind-EHABI.cpp:12:10: fatal error: 'Unwind-EHABI.h' file not found
cargo:warning=   12 | #include "Unwind-EHABI.h"
cargo:warning=      |          ^~~~~~~~~~~~~~~~
cargo:warning=1 error generated.
    exit code: 1
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants